package com.xmall.order.define.config;

import com.xmall.msg.queue.OrderModule;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class AmqpPrivateExchangeConfig {

    @Resource
    private RabbitAdmin rabbitAdmin;

    /**
     * 公共直接交换机
     */
    @Bean
    public Exchange orderDirectExchange() {
        DirectExchange exchange = new DirectExchange(OrderModule.CommonExchange.ORDER_DIRECT_EXCHANGE);
        rabbitAdmin.declareExchange(exchange);
        return exchange;
    }

    /**
     * 订单创建流向
     */
    @Bean
    public Exchange orderCreateFanoutExchange() {
        FanoutExchange exchange = new FanoutExchange(OrderModule.OrderCreate.ORDER_CREATE_FANOUT_EXCHANGE);
        rabbitAdmin.declareExchange(exchange);
        return exchange;
    }
    @Bean
    public Queue orderCreateQueue() {
        Queue queue = new Queue(OrderModule.OrderCreate.ORDER_CREATE_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding orderCreateBinding() {
        Binding binding = BindingBuilder.bind(orderCreateQueue()).to(orderCreateFanoutExchange()).with(OrderModule.OrderCreate.ORDER_CREATE_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }


    /**
     * 订单支付检查流向
     * 创建订单发送消息：路由键（order.delay.order.pay.check.key） --> 直接交换机（order.order.direct.exchange）
     *                                                       --> 延时队列（order.delay.order.pay.check.queue）
     * 延时时间到达：路由键（order.order.pay.check.key）          --> 直接交换机（order.order.direct.exchange）
     *                                                       --> 队列（order.order.pay.check.queue）
     */
    @Bean
    public Queue delayOrderPayCheckQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", OrderModule.CommonExchange.ORDER_DIRECT_EXCHANGE);
        args.put("x-dead-letter-routing-key", OrderModule.OrderPayCheck.ORDER_PAY_CHECK_ROUTING_KEY);
        Queue queue = new Queue(OrderModule.OrderPayCheck.DELAY_ORDER_PAY_CHECK_QUEUE, true, false, false, args);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding delayOrderPayCheckBinding() {
        Binding binding = BindingBuilder.bind(delayOrderPayCheckQueue()).to(orderDirectExchange()).with(OrderModule.OrderPayCheck.DELAY_ORDER_PAY_CHECK_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    @Bean
    public Queue orderPayCheckQueue() {
        Queue queue = new Queue(OrderModule.OrderPayCheck.ORDER_PAY_CHECK_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding orderPayCheckBinding() {
        Binding binding = BindingBuilder.bind(orderPayCheckQueue()).to(orderDirectExchange()).with(OrderModule.OrderPayCheck.ORDER_PAY_CHECK_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 订单退款流向
     * 订单退款：路由键（order.order.refund.key） --> 直接交换机（order.order.direct.exchange）
     *                                        --> 队列（order.order.refund.queue）
     */
    @Bean
    public Queue orderRefundQueue() {
        Queue queue = new Queue(OrderModule.OrderRefund.ORDER_REFUND_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding orderRefundBinding() {
        Binding binding = BindingBuilder.bind(orderRefundQueue()).to(orderDirectExchange()).with(OrderModule.OrderRefund.ORDER_REFUND_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    /**
     * 订单取消检查流向
     * 创建订单发送消息：路由键（order.delay.order.cancel.check.key） --> 直接交换机（order.order.direct.exchange）
     *                                                          --> 延时队列（order.delay.order.cancel.check.queue）
     * 延时时间到达：路由键（order.order.cancel.check.key） --> 直接交换机（order.order.direct.exchange）
     *                                                 --> 队列（order.order.cancel.check.queue）
     */
    @Bean
    public Queue delayOrderCancelCheckQueue() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-dead-letter-exchange", OrderModule.CommonExchange.ORDER_DIRECT_EXCHANGE);
        args.put("x-dead-letter-routing-key", OrderModule.OrderCancelCheck.ORDER_CANCEL_CHECK_ROUTING_KEY);
        Queue queue = new Queue(OrderModule.OrderCancelCheck.DELAY_ORDER_CANCEL_CHECK_QUEUE, true, false, false, args);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding delayOrderCancelCheckBinding() {
        Binding binding = BindingBuilder.bind(delayOrderCancelCheckQueue()).to(orderDirectExchange()).with(OrderModule.OrderCancelCheck.DELAY_ORDER_CANCEL_CHECK_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }

    @Bean
    public Queue orderCancelCheckQueue() {
        Queue queue = new Queue(OrderModule.OrderCancelCheck.ORDER_CANCEL_CHECK_QUEUE, true, false, false);
        rabbitAdmin.declareQueue(queue);
        return queue;
    }
    @Bean
    public Binding orderCancelCheckBinding() {
        Binding binding = BindingBuilder.bind(orderCancelCheckQueue()).to(orderDirectExchange()).with(OrderModule.OrderCancelCheck.ORDER_CANCEL_CHECK_ROUTING_KEY).noargs();
        rabbitAdmin.declareBinding(binding);
        return binding;
    }
}
